
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.mystd.all;

entity instructionBlock is 
	port (
		clk			: in std_logic;		-- signal takta
		reset		: in std_logic;		-- RESET signal  	
    	
		M3Bus 		: in bus32;			-- interna magistrala M3
		loadIR		: in std_logic;		-- upravljacki signal kojim se puni sadrzaj registra IR
    									-- sa linija M3Bus											
		clrIR		: in std_logic;		-- signal kojim se resetuje vrednost registra IR		
		
		rdValue		: out bus5;			-- indeks RD operanda
		rs1Value	: out bus5;			-- indeks RS1 operanda
		rs2Value	: out bus5;			-- indeks RS2 operanda
		
		immValue	: out bus32;		-- neposredna vrednost 		
		opcode      : out bus6			-- opcode instrukcije
		    											
    ); 
     
end instructionBlock;     
        

architecture instructionBlock of instructionBlock is
    
    signal IRregister : bus32;		-- IR registar - instrukcijski registar
               
begin  
	
	process
	begin
		wait until clk = '1';
		
		if(reset = '1') then
			-- reset ima najvisi prioritet, resetujemo vrednost IR registra			
			IRregister <= X"00_00_00_00";
		else			
			if(clrIR = '1') then 	
				-- aktivan je signal clrIR - resetujemo vrednost IR registra, popunjavamo nulama				
				IRregister <= X"00_00_00_00";     	
			elsif(loadIR = '1') then				
				-- aktivan je signal loadIR, popunjavamo IR registar sadrzajem sa linije M3Bus						
				IRregister <= M3Bus;		
			end if;
		 end if;		-- kraj if(reset = '1')
			 
	end process;		                	  
	
	opcode <= IRregister(5 downto 0);					-- odredjivanje opcode-a instrukcije
	rdValue <= bit_reverse(IRregister(10 downto 6));	-- odredjivanje indeksa RD operanda
	rs1Value <= bit_reverse(IRregister(15 downto 11));	-- odredjivanje indeksa RS1 operanda
	rs2Value <= bit_reverse(IRregister(20 downto 16));	-- odredjivanje indeksa RS2 operanda
	
	-- odredjivanje neposredne vrednosti
	
	immValue <= (31 downto 16 => IRregister(16)) & bit_reverse(IRregister(31 downto 16))
				when (
					 	 IRregister(5 downto 0) = LOADinstr OR IRregister(5 downto 0) = JSRinstr OR
					  	 IRregister(5 downto 0) = ADDIinstr OR IRregister(5 downto 0) = SUBIinstr OR
					  	 IRregister(5 downto 0) = MOVIinstr OR IRregister(5 downto 0) = JMPinstr 
					 ) else
				(31 downto 16 => IRregister(6)) & bit_reverse(IRregister(10 downto 6)) & bit_reverse(IRregister(31 downto 21)) 
				when (
						 IRregister(5 downto 0) = BEQinstr OR IRregister(5 downto 0) = BNQinstr OR
						 IRregister(5 downto 0) = BLTinstr OR IRregister(5 downto 0) = BGTinstr OR
						 IRregister(5 downto 0) = BLEinstr OR IRregister(5 downto 0) = BGEinstr OR
						 IRregister(5 downto 0) = STOREinstr
					 ) else
				(31 downto 5 => '0') & bit_reverse(IRregister(20 downto 16))
				when (
						IRregister(5 downto 0) = SHLinstr OR IRregister(5 downto 0) = SARinstr OR
						IRregister(5 downto 0) = SHRinstr OR IRregister(5 downto 0) = RORinstr OR
						IRregister(5 downto 0) = ROLinstr
							
					 ) else
				X"00_00_00_00";
	
end instructionBlock;








